<?php
/**
 * | 节程 [ 节程赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 *  | Copyright (c) 2020~2029 温州惊蛰网络科技有限公司 All rights reserved.
 * +----------------------------------------------------------------------
 *  | Licensed 节程并不是自由软件，未经许可不能去掉节程相关版权
 * +----------------------------------------------------------------------
 */
declare (strict_types = 1);

namespace app\madmin\model;

use think\Exception;
use app\madmin\validate\SeckillValidate;
use think\model\concern\SoftDelete;

class Seckill extends BaseModel
{
    use SoftDelete;
    protected $deleteTime = 'delete_time';
//    protected $globalScope = 'mallId';

    private static $rules = [
        'use_agent' => '0', // 分销
        'limit_type' => '[1, 3, 0]', // 限购次数 0不开启；{选项，活动期内每人最多购买, 活动期内每人每天最多购买}
        'is_show' => '[0, null]', // 活动预热 {0,time}关闭；{1是，时间}
    ];

    private static function getRules($rules)
    {
        $w = array_diff(self::$rules, array_intersect_key(self::$rules, $rules));
        if (count($w) > 0) {
            throw new Exception(implode(",", array_keys($w)) . "不可为空", HTTP_NOTACCEPT);
        }
        if (is_array($rules['is_show'])) {
            if ($rules['is_show'][0] == 1) {
                $rules['show_time'] = $rules['is_show'][1];
            } else {
                $rules['show_time'] = null;
            }
            unset($rules['is_show']);
        }
        return $rules;
    }

    public function __construct(array $data = [])
    {
        parent::__construct($data);
    }

    public function commodity()
    {
        return $this->hasMany(SeckillCommodity::class, "seckill_id", "id");
    }

    /**
     * @param $data
     * @return mixed
     * @throws
     */
    public static function check($data)
    {
        // 活动状态
        $data['status'] = 1;
        $date = date("Y-m-d H:i:s", time());
        if ($data['end_time'] < $date) {
            $data['status'] = 2;
        } else if ($data['start_time'] > $date) {
            $data['status'] = 0;
        }
        // 验证规则设置
        $rule_arr = self::getRules($data['rules']);
        $rule_arr['status'] = $data['status'];
        $rule_arr['end_time'] = $data['end_time'];
        // 验证商品
        $validate = new SeckillValidate();
        $commodity = $data['commodity'];

        foreach ($commodity as $key => $value) {
            $commodity[$key] = array_merge($value, $rule_arr);
            // 下单前减库存
            $cc = Commodity::field("inventory_type,name,total,sell")->find($value['commodity_id']);
            if ($cc['inventory_type'] != 1) {
                throw new Exception("“".$cc['name']."”需设置为下单减库存！", HTTP_NOTACCEPT);
            }
            self::checkStock($value, $cc);
            // 是否拼团中
            $is_group = SeckillCommodity::with('goods')->where(['commodity_id' => $value['commodity_id']])
                ->where([['status', 'in', [0,1]]])
                ->find();
            if (!is_null($is_group)) {
                throw new Exception("“".$is_group['goods']['name']."”有".$is_group['status_text']."的拼团！", HTTP_NOTACCEPT);
            }
            // 是否有商品预售中
            $is_presell = PresellCommodity::with('goods')->where(['commodity_id' => $value['commodity_id']])
                ->where([['status', 'in', [0,1]]])
                ->find();
            if (!is_null($is_presell)) {
                throw new Exception("“".$is_presell['goods']['name']."”已经设置了".$is_presell['status_text']."预售！", HTTP_NOTACCEPT);
            }
            // 单规格
            if ($value['has_sku'] == 0) {
                $check_commodity = $validate->scene('commodity')->check($value);
                if (!$check_commodity) {
                    throw new Exception($validate->getError(), HTTP_NOTACCEPT);
                }
                unset($commodity[$key]['skus']);
            }
        }
        // 处理数据
        $data['rules'] = json_encode($data['rules']);
        unset($data['commodity']);
        return ['group' => $data, 'commodity' => $commodity];
    }

    private static function checkStock($value, $item)
    {
        if ($value['has_sku'] == 1) {
            foreach ($value["skus"] as $sk => $sv) {
                $sku = SkuInventory::where('sku_id', $sv['sku_id'])->find();
                $stock = $sku['total'] - $sku['sell'];
                self::checkOne($sv['activity_stock'], $stock, $sv['activity_price'], $item['name']);
            }
        } else {
            $stock = $item['total'] - $item['sell'];
            self::checkOne($value['activity_stock'], $stock, $value['activity_price'], $item['name']);
        }
    }

    private static function checkOne($activity_stock, $total, $activity_price, $name)
    {
        if ($activity_stock <= 0) {
            throw new Exception("“".$name."”请设置正确的库存！", HTTP_NOTACCEPT);
        }
        if ($activity_price <= 0) {
            throw new Exception("“".$name."”请设置正确的价格！", HTTP_NOTACCEPT);
        }
        if ($activity_stock > $total) {
            throw new Exception("“".$name."”活动库存需小于现库存！", HTTP_NOTACCEPT);
        }
    }
}
